package org.jhub1.system.xmpp.config;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.jhub1.system.env.Env;
import org.jhub1.system.xmpp.commands.RequestMessage;
import org.jhub1.system.xmpp.log.LogAdapter;

public class ConfigAdapter {

	private static ConfigAdapter instance = null;
	private static LogAdapter log = null;
	private static CompositeConfiguration  cConfig = null;
    /**
     * Name of the file we are looking for to read the configuration.
     */
 //   public static final String DEFAULT_RESOURCE_NAME = "JabberProxy.config";
    public static final String PROPERTY = "xmpp_proxy";	
       
	protected ConfigAdapter() {	
		cConfig = new CompositeConfiguration();
		cConfig.addConfiguration(new SystemConfiguration());
		try {
			cConfig.addConfiguration(new PropertiesConfiguration(Env.getMainConfig("/home/marek/workspaceJuno/JabberClient/src/JabberProxy.config")));
		} catch (ConfigurationException e) {
			log.error("Config: '" + Env.getMainConfig("/home/marek/workspaceJuno/JabberClient/src/JabberProxy.config") + "' is not added: " + e.getMessage());
		}
	}
	
	public static ConfigAdapter getInstance(LogAdapter log) {
		if (instance == null) {
			instance = new ConfigAdapter();
		}
		return instance;
	}
	
	public CompositeConfiguration getConfigurationInstance() {
		return cConfig;
	}

	public CompositeConfiguration getCCI() {
		return cConfig;
	}
	
	public void addConfig(String path) {
		try {
			cConfig.addConfiguration(new PropertiesConfiguration(Env.getLocalConfig(path)));
		} catch (ConfigurationException e) {
			log.error("Config: " + path + " is not added: " + e.getMessage());
		}
	}
	
    public String getInitialStatus() {
        return 	parseStatus(cConfig.getString(getPName("initstatus")));
    }
//
    public int getPort() {
        return cConfig.getInt(getPName("port"));
    }
  //  
    public boolean isLogEnabled() {
        return cConfig.getBoolean(getPName("log"));
    }
   // 
    public String getResource() {
        return cConfig.getString(getPName("resource"));
    }
   // 
    public String getPassword() {
        return cConfig.getString(getPName("password"));
    }
    //
    public String getJID() {
        return cConfig.getString(getPName("jid"));
    }
    //
    public String getServer() {
        return cConfig.getString(getPName("server"));
    }
    //
    public String getTrusted() {
        return cConfig.getString(getPName("trusted"));
    }
    //
    public boolean isJavaDebugEnabled() {
        return cConfig.getBoolean(getPName("java_adv_debug"));
    }
    //
    public boolean isPresenceLogEnabled() {
        return cConfig.getBoolean(getPName("log_presence"));
    }
    //
    public String getSessionPassword() {
        return cConfig.getString(getPName("session_pass"));
    }
    //
    public String getPIDFile() {
        return cConfig.getString(getPName("pidfile"));
    }
    
    protected String getPName(String name) {
    	return PROPERTY + "." + name;
    }
	//
    public boolean isTrusted(String from) {
        boolean isApproved = false;
    	String[] approveds = cConfig.getStringArray(getPName("trusted"));
    	for(String approved : approveds) {
			if(from.contains(approved)) {
				isApproved = true;
			}
    	}
        return isApproved;
    }
  
    public boolean isTrusted(RequestMessage rmsg) {
        boolean isApproved = false;
        isApproved = isTrusted(rmsg.getJid());
        if (isApproved) {
        	return true;
        } else {
        	isApproved = isTrusted(rmsg.getUName());
        }
        return isApproved;
    }
    
    public boolean isApproved(String from) {
        boolean isTrusted = false;
    	String[] trusteds = cConfig.getStringArray(getPName("approved"));
    	for(String trusted : trusteds) {
			if(from.contains(trusted)) {
				isTrusted = true;
			}
    	}
        return isTrusted;
    }
    
	public String getNick() {
    	String jid = cConfig.getString(getPName("jid"));
    	String[] parts = jid.split("\\@");
    	return parts[0];
    }
    
	public String getDomain() {
    	String jid = cConfig.getString(getPName("jid"));
    	String[] parts = jid.split("\\@");
    	return parts[1];
    }
	
	private static String parseStatus(String text) {
		Map<String, String> ips = new HashMap<String, String>();
	    try {
	         Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
	         while(e.hasMoreElements()) {
	            NetworkInterface ni = (NetworkInterface) e.nextElement();
	            Enumeration<InetAddress> e2 = ni.getInetAddresses();
	            StringBuilder sb = new StringBuilder();
	            while (e2.hasMoreElements()){
	               InetAddress ipadd = (InetAddress) e2.nextElement();
	               if(!ipadd.getHostAddress().contains("%")) {
	               sb.append(ipadd.getHostAddress() + " ");
	               }
	            }
	            ips.put(ni.getName().toString(), sb.toString());
	         }
	      }
	      catch (Exception e) {
	    	 // ip = "err";
	      }
	    if(ips.containsKey("eth0")) {
	    	return text.replace("%eth0%", ips.get("eth0"));
	    } else {
	    	return text.replace("%eth0%", "");
	    }
	}
}
